package com.zenithmind.version.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zenithmind.version.pojo.domain.MergeRequest;
import com.zenithmind.version.pojo.vo.MergeRequestVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import java.util.List;

/**
 * 合并请求Mapper接口
 * 
 * @author ZenithMind Team
 * @since 2025-01-09
 */
@Mapper
public interface MergeRequestMapper extends BaseMapper<MergeRequest> {

    /**
     * 分页查询合并请求（包含关联信息）
     * 
     * @param page 分页参数
     * @param repositoryId 仓库ID
     * @param status 状态
     * @param authorId 作者ID
     * @param assigneeId 指派人ID
     * @return 分页结果
     */
    IPage<MergeRequestVO> selectMergeRequestPageWithDetails(Page<MergeRequestVO> page,
                                                           @Param("repositoryId") String repositoryId,
                                                           @Param("status") Integer status,
                                                           @Param("authorId") String authorId,
                                                           @Param("assigneeId") String assigneeId);

    /**
     * 获取合并请求详情
     * 
     * @param id 合并请求ID
     * @return 合并请求详情
     */
    MergeRequestVO selectMergeRequestDetail(@Param("id") String id);

    /**
     * 获取仓库的合并请求列表
     * 
     * @param repositoryId 仓库ID
     * @param status 状态
     * @param limit 限制数量
     * @return 合并请求列表
     */
    @Select("SELECT mr.*, u1.real_name as author_name, u2.real_name as assignee_name, " +
            "r.name as repository_name " +
            "FROM merge_request mr " +
            "LEFT JOIN user u1 ON mr.author_id = u1.id " +
            "LEFT JOIN user u2 ON mr.assignee_id = u2.id " +
            "LEFT JOIN repository r ON mr.repository_id = r.id " +
            "WHERE mr.repository_id = #{repositoryId} " +
            "AND (#{status} IS NULL OR mr.status = #{status}) " +
            "AND mr.deleted = 0 " +
            "ORDER BY mr.create_time DESC " +
            "LIMIT #{limit}")
    List<MergeRequestVO> selectRepositoryMergeRequests(@Param("repositoryId") String repositoryId,
                                                      @Param("status") Integer status,
                                                      @Param("limit") Integer limit);

    /**
     * 获取用户创建的合并请求
     * 
     * @param authorId 作者ID
     * @param status 状态
     * @param limit 限制数量
     * @return 合并请求列表
     */
    @Select("SELECT mr.*, u1.real_name as author_name, u2.real_name as assignee_name, " +
            "r.name as repository_name " +
            "FROM merge_request mr " +
            "LEFT JOIN user u1 ON mr.author_id = u1.id " +
            "LEFT JOIN user u2 ON mr.assignee_id = u2.id " +
            "LEFT JOIN repository r ON mr.repository_id = r.id " +
            "WHERE mr.author_id = #{authorId} " +
            "AND (#{status} IS NULL OR mr.status = #{status}) " +
            "AND mr.deleted = 0 " +
            "ORDER BY mr.create_time DESC " +
            "LIMIT #{limit}")
    List<MergeRequestVO> selectUserMergeRequests(@Param("authorId") String authorId,
                                                @Param("status") Integer status,
                                                @Param("limit") Integer limit);

    /**
     * 获取指派给用户的合并请求
     * 
     * @param assigneeId 指派人ID
     * @param status 状态
     * @param limit 限制数量
     * @return 合并请求列表
     */
    @Select("SELECT mr.*, u1.real_name as author_name, u2.real_name as assignee_name, " +
            "r.name as repository_name " +
            "FROM merge_request mr " +
            "LEFT JOIN user u1 ON mr.author_id = u1.id " +
            "LEFT JOIN user u2 ON mr.assignee_id = u2.id " +
            "LEFT JOIN repository r ON mr.repository_id = r.id " +
            "WHERE mr.assignee_id = #{assigneeId} " +
            "AND (#{status} IS NULL OR mr.status = #{status}) " +
            "AND mr.deleted = 0 " +
            "ORDER BY mr.create_time DESC " +
            "LIMIT #{limit}")
    List<MergeRequestVO> selectAssignedMergeRequests(@Param("assigneeId") String assigneeId,
                                                    @Param("status") Integer status,
                                                    @Param("limit") Integer limit);

    /**
     * 检查合并冲突
     * 
     * @param repositoryId 仓库ID
     * @param sourceBranch 源分支
     * @param targetBranch 目标分支
     * @return 冲突信息
     */
    Object checkMergeConflicts(@Param("repositoryId") String repositoryId,
                              @Param("sourceBranch") String sourceBranch,
                              @Param("targetBranch") String targetBranch);

    /**
     * 获取合并请求的文件变更
     * 
     * @param mergeRequestId 合并请求ID
     * @return 文件变更列表
     */
    List<Object> selectMergeRequestChanges(@Param("mergeRequestId") String mergeRequestId);

    /**
     * 获取合并请求的提交列表
     * 
     * @param mergeRequestId 合并请求ID
     * @return 提交列表
     */
    @Select("SELECT c.* FROM commit c " +
            "INNER JOIN merge_request mr ON c.branch_name = mr.source_branch " +
            "WHERE mr.id = #{mergeRequestId} " +
            "AND c.repository_id = mr.repository_id " +
            "AND c.commit_time >= mr.create_time " +
            "AND c.deleted = 0 " +
            "ORDER BY c.commit_time DESC")
    List<Object> selectMergeRequestCommits(@Param("mergeRequestId") String mergeRequestId);

    /**
     * 执行合并
     * 
     * @param mergeRequestId 合并请求ID
     * @param mergeCommitId 合并提交ID
     * @param mergerId 合并者ID
     * @return 影响行数
     */
    @Update("UPDATE merge_request SET " +
            "status = 3, " +
            "merge_commit_id = #{mergeCommitId}, " +
            "merged_by = #{mergerId}, " +
            "merged_at = NOW(), " +
            "update_time = NOW() " +
            "WHERE id = #{mergeRequestId}")
    int executeMerge(@Param("mergeRequestId") String mergeRequestId,
                    @Param("mergeCommitId") String mergeCommitId,
                    @Param("mergerId") String mergerId);

    /**
     * 关闭合并请求
     * 
     * @param mergeRequestId 合并请求ID
     * @param closerId 关闭者ID
     * @param reason 关闭原因
     * @return 影响行数
     */
    @Update("UPDATE merge_request SET " +
            "status = 4, " +
            "closed_by = #{closerId}, " +
            "closed_at = NOW(), " +
            "close_reason = #{reason}, " +
            "update_time = NOW() " +
            "WHERE id = #{mergeRequestId}")
    int closeMergeRequest(@Param("mergeRequestId") String mergeRequestId,
                         @Param("closerId") String closerId,
                         @Param("reason") String reason);

    /**
     * 重新打开合并请求
     * 
     * @param mergeRequestId 合并请求ID
     * @param reopenerId 重新打开者ID
     * @return 影响行数
     */
    @Update("UPDATE merge_request SET " +
            "status = 1, " +
            "reopened_by = #{reopenerId}, " +
            "reopened_at = NOW(), " +
            "update_time = NOW() " +
            "WHERE id = #{mergeRequestId}")
    int reopenMergeRequest(@Param("mergeRequestId") String mergeRequestId,
                          @Param("reopenerId") String reopenerId);

    /**
     * 添加审核者
     * 
     * @param mergeRequestId 合并请求ID
     * @param reviewerId 审核者ID
     * @param addedBy 添加者ID
     * @return 影响行数
     */
    int addReviewer(@Param("mergeRequestId") String mergeRequestId,
                   @Param("reviewerId") String reviewerId,
                   @Param("addedBy") String addedBy);

    /**
     * 移除审核者
     * 
     * @param mergeRequestId 合并请求ID
     * @param reviewerId 审核者ID
     * @return 影响行数
     */
    int removeReviewer(@Param("mergeRequestId") String mergeRequestId,
                      @Param("reviewerId") String reviewerId);

    /**
     * 提交审核意见
     * 
     * @param mergeRequestId 合并请求ID
     * @param reviewerId 审核者ID
     * @param status 审核状态
     * @param comment 审核意见
     * @return 影响行数
     */
    int submitReview(@Param("mergeRequestId") String mergeRequestId,
                    @Param("reviewerId") String reviewerId,
                    @Param("status") Integer status,
                    @Param("comment") String comment);

    /**
     * 获取合并请求的审核记录
     * 
     * @param mergeRequestId 合并请求ID
     * @return 审核记录
     */
    List<Object> selectMergeRequestReviews(@Param("mergeRequestId") String mergeRequestId);

    /**
     * 搜索合并请求
     * 
     * @param keyword 关键词
     * @param repositoryId 仓库ID
     * @param status 状态
     * @param limit 限制数量
     * @return 合并请求列表
     */
    @Select("SELECT mr.*, u1.real_name as author_name, u2.real_name as assignee_name, " +
            "r.name as repository_name " +
            "FROM merge_request mr " +
            "LEFT JOIN user u1 ON mr.author_id = u1.id " +
            "LEFT JOIN user u2 ON mr.assignee_id = u2.id " +
            "LEFT JOIN repository r ON mr.repository_id = r.id " +
            "WHERE (#{repositoryId} IS NULL OR mr.repository_id = #{repositoryId}) " +
            "AND (#{status} IS NULL OR mr.status = #{status}) " +
            "AND mr.deleted = 0 " +
            "AND (mr.title LIKE CONCAT('%', #{keyword}, '%') " +
            "OR mr.description LIKE CONCAT('%', #{keyword}, '%')) " +
            "ORDER BY mr.create_time DESC " +
            "LIMIT #{limit}")
    List<MergeRequestVO> searchMergeRequests(@Param("keyword") String keyword,
                                            @Param("repositoryId") String repositoryId,
                                            @Param("status") Integer status,
                                            @Param("limit") Integer limit);

    /**
     * 获取合并请求统计
     * 
     * @param repositoryId 仓库ID
     * @return 统计信息
     */
    Object selectMergeRequestStatistics(@Param("repositoryId") String repositoryId);

    /**
     * 获取用户合并请求统计
     * 
     * @param userId 用户ID
     * @return 统计信息
     */
    @Select("SELECT " +
            "COUNT(CASE WHEN author_id = #{userId} THEN 1 END) as created_count, " +
            "COUNT(CASE WHEN assignee_id = #{userId} THEN 1 END) as assigned_count, " +
            "COUNT(CASE WHEN merged_by = #{userId} THEN 1 END) as merged_count, " +
            "COUNT(CASE WHEN status = 1 AND author_id = #{userId} THEN 1 END) as open_count " +
            "FROM merge_request " +
            "WHERE (author_id = #{userId} OR assignee_id = #{userId} OR merged_by = #{userId}) " +
            "AND deleted = 0")
    Object selectUserMergeRequestStatistics(@Param("userId") String userId);
}
